function LinkedList() {
    function Node(data) {
        this.data = data
        this.next = null
    }
    //属性
    this.head = null
    this.length = 0
    //index可以为负数，获取对应的index正数值，如果超出范围则报错
    LinkedList.prototype.getPositiveIndex = function(index){
        if(index >= this.length || index < -this.length){
            throw (`the index is not illegal `)
        }
        return index >=0 ? index : index + this.length
    }
    //append方法，向链表最后追加一个节点
    LinkedList.prototype.append = function (data) {
        let newNode = new Node(data)
        //如果是第一个节点
        if (this.length == 0) {
            this.head = newNode
        } else {
            //移动指针到最后一个节点
            let currentNode = this.head
            while (currentNode.next) {
                currentNode = currentNode.next
            }
            currentNode.next = newNode
        }
        this.length++
        return newNode.data
    }
    //toString方法，把链表内容转换成字符串
    LinkedList.prototype.toString = function () {
        let currentNode = this.head
        let resultString = ''
        while (currentNode) {
            resultString += ',' + currentNode.data
            currentNode = currentNode.next
        }
        return resultString.replace(',', '')

    }
    LinkedList.prototype.valueOf = this.toString
    //get方法，根据索引值获取数据
    LinkedList.prototype.get = function (index) {
        let node = this.getNode(index)
        return node ? node.data : null
    }
    //get方法，根据索引值获取节点
    LinkedList.prototype.getNode = function (index) {
        let currentNode = this.head
        //索引值可以是负数，当为负数时转换为对应的正数
        index = index < 0 ? this.length + index : index
        //如果索引的值大于长度或者小于0，则返回空值
        if (index < 0 || index >= this.length) {
            return null
        }
        for (let i = 0; i < index; i++) {
            currentNode = currentNode.next
            if (!currentNode) {
                return null
            }
        }
        return currentNode
    }
    // insert方法，在节点之前插入
    LinkedList.prototype.insert = function (index, data) { 
        let idx = this.getPositiveIndex(index)
        let newNode = new Node(data)
        // 如果是第一个节点
        if (idx == 0 ) {
            console.log('idx=0')
            // let oldHead = this.head
            // this.head = newNode
            // newNode.next = oldHead 
            newNode.next = this.head
            this.head.next = newNode      
        }else{
            let before = this.getNode(idx - 1)
            let currentNode = before.next
            before.next = newNode
            newNode.next = currentNode
        }
        this.length++
        return this
    }
    //indexOf方法，找到元素的索引，如果不存在则返回-1
    LinkedList.prototype.indexOf = function (element) {
        let i = 0;
        let currentNode = this.head
        while (i < this.length) {
            if (currentNode.data == element) {
                return i
            }
            currentNode = currentNode.next
            i++
        }
        return -1
    }
    //update方法，更新某个位置的值
    LinkedList.prototype.updata = function (index, value) {
        let idx = this.getPositiveIndex(index)
        let currentNode = this.getNode(idx)
        currentNode.data = value
        return this
    }
    //removeAt方法，从列表中的特定位置移除一项
    LinkedList.prototype.removeAt = function (index) {
        let idx = this.getPositiveIndex(index)
        let removeData = null;
        if (idx == 0) {
            removeData = this.head.data
            this.head = this.head.next
        } else {
            let before = this.getNode(idx - 1)
            let currentNode = before.next
            let after = currentNode.next
            before.next = after
            removeData = currentNode.data
        }
        this.length--
        return removeData
    }
    //remove方法，从链表中删除对应的元素
    LinkedList.prototype.remove = function (element) {
        let removeData = element
        let before = this.head
        let currentNode = this.head.next
        //如果要删除头部节点
        if (before.data == element) {
            this.head = before.next
            this.length--
            return removeData
        } else {
            while (currentNode) {
                if (currentNode.data == element) {
                    before.next = currentNode.next
                    this.length--
                    return removeData
                }
                before = currentNode
                currentNode = currentNode.next
            }
        }
    }

    LinkedList.prototype.isEmpty = function(){
        return this.length == 0
    }

    LinkedList.prototype.size = function(){
        return this.length
    }
}
let linkedList = new LinkedList()
linkedList.append('a')
linkedList.append('bcd')
linkedList.append('cde')
linkedList.insert(0, 'insert')
// linkedList.append('bcd')
// console.log(linkedList.toString())
// linkedList.indexOf('bcd')
// linkedList.indexOf('bcde')
